www.gusucode.com > C++ 屏幕录像简单演示 > C++ 屏幕录像简单演示/code/AviFile.cpp
#include "StdAfx.h" #include "avifile.h" #ifndef __countof #define __countof(x) ((sizeof(x)/sizeof(x[0]))) #endif CAviFile:: CAviFile(LPCSTR lpszFileName /* =_T("Output.avi") */, DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */, DWORD dwFrameRate /* = 1 */) { AVIFileInit(); m_hHeap=NULL; m_hAviDC=NULL; m_lpBits=NULL; m_lSample=NULL; m_pAviFile=NULL; m_pAviStream=NULL; m_pAviCompressedStream=NULL; m_dwFCCHandler = dwCodec; m_dwFrameRate = dwFrameRate; _tcscpy(m_szFileName, lpszFileName); _tcscpy(m_szErrMsg, _T("Method Succeeded")); m_szErrMsg[__countof(m_szErrMsg)-1] = _T('\0'); pAppendFrame[0]= &CAviFile::AppendDummy; // VC8 requires & for Function Pointer; Remove it if your compiler complains; pAppendFrame[1]= &CAviFile::AppendFrameFirstTime; pAppendFrame[2]= &CAviFile::AppendFrameUsual; pAppendFrameBits[0]=&CAviFile::AppendDummy; pAppendFrameBits[1]=&CAviFile::AppendFrameFirstTime; pAppendFrameBits[2]=&CAviFile::AppendFrameUsual; m_nAppendFuncSelector=1; //0=Dummy 1=FirstTime 2=Usual } CAviFile::~CAviFile(void) { ReleaseMemory(); AVIFileExit(); } void CAviFile::ReleaseMemory() { m_nAppendFuncSelector=0; //Point to DummyFunction if(m_hAviDC) { DeleteDC(m_hAviDC); m_hAviDC=NULL; } if(m_pAviCompressedStream) { AVIStreamRelease(m_pAviCompressedStream); m_pAviCompressedStream=NULL; } if(m_pAviStream) { AVIStreamRelease(m_pAviStream); m_pAviStream=NULL; } if(m_pAviFile) { AVIFileRelease(m_pAviFile); m_pAviFile=NULL; } if(m_lpBits) { HeapFree(m_hHeap,HEAP_NO_SERIALIZE,m_lpBits); m_lpBits=NULL; } if(m_hHeap) { HeapDestroy(m_hHeap); m_hHeap=NULL; } } void CAviFile::SetErrorMessage(LPCTSTR lpszErrorMessage) { _tcsncpy(m_szErrMsg, lpszErrorMessage, __countof(m_szErrMsg)-1); } HRESULT CAviFile::InitMovieCreation(int nFrameWidth, int nFrameHeight, int nBitsPerPixel) { int nMaxWidth=GetSystemMetrics(SM_CXSCREEN),nMaxHeight=GetSystemMetrics(SM_CYSCREEN); m_hAviDC = CreateCompatibleDC(NULL); if(m_hAviDC==NULL) { SetErrorMessage("Unable to Create Compatible DC"); return E_FAIL; } if(nFrameWidth > nMaxWidth) nMaxWidth= nFrameWidth; if(nFrameHeight > nMaxHeight) nMaxHeight = nFrameHeight; m_hHeap=HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0); if(m_hHeap==NULL) { SetErrorMessage("Unable to Create Heap"); return E_FAIL; } m_lpBits=HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4); if(m_lpBits==NULL) { SetErrorMessage("Unable to Allocate Memory on Heap"); return E_FAIL; } if(FAILED(AVIFileOpen(&m_pAviFile, m_szFileName, OF_CREATE|OF_WRITE, NULL))) { SetErrorMessage("Unable to Create the Movie File"); return E_FAIL; } ZeroMemory(&m_AviStreamInfo,sizeof(AVISTREAMINFO)); m_AviStreamInfo.fccType = streamtypeVIDEO; m_AviStreamInfo.fccHandler = m_dwFCCHandler; m_AviStreamInfo.dwScale = 1; m_AviStreamInfo.dwRate = m_dwFrameRate; // Frames Per Second; m_AviStreamInfo.dwQuality = -1; // Default Quality m_AviStreamInfo.dwSuggestedBufferSize = nMaxWidth*nMaxHeight*4; SetRect(&m_AviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight); _tcscpy(m_AviStreamInfo.szName, _T("Video Stream")); if(FAILED(AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo))) { SetErrorMessage("Unable to Create Video Stream in the Movie File"); return E_FAIL; } ZeroMemory(&m_AviCompressOptions,sizeof(AVICOMPRESSOPTIONS)); m_AviCompressOptions.fccType=streamtypeVIDEO; m_AviCompressOptions.fccHandler=m_AviStreamInfo.fccHandler; m_AviCompressOptions.dwFlags=AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID;//|AVICOMPRESSF_DATARATE; m_AviCompressOptions.dwKeyFrameEvery=15; //m_AviCompressOptions.dwBytesPerSecond=1000/8; m_AviCompressOptions.dwQuality=10000; if(FAILED(AVIMakeCompressedStream(&m_pAviCompressedStream,m_pAviStream,&m_AviCompressOptions,NULL))) { SetErrorMessage("Unable to Create Compressed Stream: Check your CODEC options"); return E_FAIL; } BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biWidth = nFrameWidth; bmpInfo.bmiHeader.biHeight = nFrameHeight; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biBitCount = nBitsPerPixel; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth*bmpInfo.bmiHeader.biHeight*bmpInfo.bmiHeader.biBitCount/8; if(FAILED(AVIStreamSetFormat(m_pAviCompressedStream,0,(LPVOID)&bmpInfo, bmpInfo.bmiHeader.biSize))) { SetErrorMessage("Unable to Set Video Stream Format"); return E_FAIL; } return S_OK; // Everything went Fine } HRESULT CAviFile::AppendFrameFirstTime(HBITMAP hBitmap) { BITMAP Bitmap; GetObject(hBitmap, sizeof(BITMAP), &Bitmap); if(SUCCEEDED(InitMovieCreation( Bitmap.bmWidth, Bitmap.bmHeight, Bitmap.bmBitsPixel))) { m_nAppendFuncSelector=2; //Point to the UsualAppend Function return AppendFrameUsual(hBitmap); } ReleaseMemory(); return E_FAIL; } HRESULT CAviFile::AppendFrameUsual(HBITMAP hBitmap) { BITMAPINFO bmpInfo; bmpInfo.bmiHeader.biBitCount=0; bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(m_hAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(m_hAviDC,hBitmap,0,bmpInfo.bmiHeader.biHeight,m_lpBits,&bmpInfo,DIB_RGB_COLORS); if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,m_lpBits,bmpInfo.bmiHeader.biSizeImage,0,NULL,NULL))) { SetErrorMessage(_T("Unable to Write Video Stream to the output Movie File")); ReleaseMemory(); return E_FAIL; } return S_OK; } HRESULT CAviFile::AppendDummy(HBITMAP) { return E_FAIL; } HRESULT CAviFile::AppendNewFrame(HBITMAP hBitmap) { return (this->*pAppendFrame[m_nAppendFuncSelector])((HBITMAP)hBitmap); } HRESULT CAviFile::AppendNewFrame(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel) { return (this->*pAppendFrameBits[m_nAppendFuncSelector])(nWidth,nHeight,pBits,nBitsPerPixel); } HRESULT CAviFile::AppendFrameFirstTime(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel) { if(SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel))) { m_nAppendFuncSelector=2; //Point to the UsualAppend Function return AppendFrameUsual(nWidth, nHeight, pBits, nBitsPerPixel); } ReleaseMemory(); return E_FAIL; } HRESULT CAviFile::AppendFrameUsual(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel) { DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8; if(FAILED(AVIStreamWrite(m_pAviCompressedStream,m_lSample++,1,pBits,dwSize,0,NULL,NULL))) { SetErrorMessage(_T("Unable to Write Video Stream to the output Movie File")); ReleaseMemory(); return E_FAIL; } return S_OK; } HRESULT CAviFile::AppendDummy(int nWidth, int nHeight, LPVOID pBits,int nBitsPerPixel) { return E_FAIL; }